package org.example.rowing.service;

import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.example.rowing.domain.Athlete;
import org.example.rowing.domain.Event;
import org.example.rowing.domain.Team;
import org.example.rowing.enums.BoatTypeEnum;
import org.example.rowing.enums.GenderEnum;
import org.example.rowing.mapper.AthleteMapper;
import org.example.rowing.mapper.RegistrationWithAthleteMapper;
import org.example.rowing.mapper.TeamMapper;
import org.example.rowing.service.impl.AthleteDataImporter;
import org.example.rowing.service.impl.TeamDataImporter;
import org.example.rowing.vo.AthleteVO;
import org.example.rowing.vo.EventVO;
import org.example.rowing.vo.TeamVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
@Slf4j
public class TeamInfoService {

    @Autowired
    private TeamMapper teamMapper;
    @Autowired
    private AthleteMapper athleteMapper;
    @Autowired
    private EventInfoService eventInfoService;
    @Autowired
    private RegistrationWithAthleteMapper registrationWithAthleteMapper;

    public TeamVO selectTeamById(Long id) {
        Team team = teamMapper.selectTeamById(id);
        TeamVO teamVO = new TeamVO(team.getId(), team.getName(), team.getCountry(), team.getCoach(),
                team.getInfo(), null);
        return teamVO;
    }

    public List<TeamVO> showTeamsByBoatType(BoatTypeEnum boatTypeEnum) {
        List<TeamVO> teamVOS = teamMapper.selectTeamVOByBoatType(boatTypeEnum.getDisplayName());
        return teamVOS;
    }

    public List<TeamVO> showTeamsByEventName(String eventName) {
        return teamMapper.selectTeamVOByEventName(eventName);
    }

    public List<TeamVO> showTeamsByEventId(Long eventId) {
        return teamMapper.selectTeamVOByEventId(eventId);
    }

    public List<AthleteVO> showAthletesByBoatType(BoatTypeEnum boatTypeEnum) {
        List<AthleteVO> athleteVOS = new ArrayList<>();
        List<TeamVO> teamVOS = teamMapper.selectTeamVOByBoatType(boatTypeEnum.getDisplayName());
        for (TeamVO teamVO : teamVOS) {
            Athlete athleteCondition = new Athlete();
            athleteCondition.setTeamId(teamVO.getId());
            List<Athlete> athletes = athleteMapper.selectAthleteByConditions(athleteCondition);
            Team team = new Team(teamVO.getId(), teamVO.getEventVO().getId(), teamVO.getName(), teamVO.getCountry(), teamVO.getCoachName(), teamVO.getInfo(), null);
            Event event = new Event(teamVO.getEventVO().getId(), teamVO.getEventVO().getName(), null, null, null, BoatTypeEnum.fromDisplayName(teamVO.getEventVO().getBoatType()));
            for (Athlete athlete : athletes) {
                AthleteVO athleteVO = new AthleteVO(athlete.getId(), athlete.getName(), athlete.getGenderEnum(),
                        athlete.getBirthDate(), team, event, athlete.getCategory());
                athleteVOS.add(athleteVO);
            }
        }
        return athleteVOS;
    }

    public void saveOrUpdateTeam(Team team) {
        if (team.getId() == null) {
            teamMapper.insertTeam(team);
            log.info("新队伍已保存: {}", team);
        } else {
            teamMapper.updateTeam(team);
            log.info("队伍已更新: {}", team);
        }
    }

    public void saveOrUpdateAthlete(Athlete athlete) {
        if (athlete.getId() == null) {
            athleteMapper.insertAthlete(athlete);
            log.info("新选手已保存: {}", athlete);
        } else {
            athleteMapper.updateAthlete(athlete);
            registrationWithAthleteMapper.updateAthleteNameByAthleteId(athlete);
            log.info("选手信息已更新: {}", athlete);
        }
    }

    public void deleteTeam(Long id) {
        Team team = new Team();
        team.setId(id);
        List<Team> teams = teamMapper.selectTeamByConditions(team);
        if (teams != null && !teams.isEmpty()) {
            teamMapper.deleteTeam(id);
            athleteMapper.deleteAthletesByTeamId(id);
            log.info("队伍已删除: {}", id);
        } else {
            log.info("此队伍暂不存在!!!");
        }
    }

    public void deleteAthlete(Long id) {
        Athlete athlete = new Athlete();
        athlete.setId(id);
        List<Athlete> athletes = athleteMapper.selectAthleteByConditions(athlete);
        if (athletes != null && !athletes.isEmpty()) {
            athleteMapper.deleteAthlete(id);
            log.info("选手已删除: {}", id);
        } else {
            log.info("此选手暂不存在!!!");
        }
    }

    public List<TeamVO> showSearchedTeams(Team teamConditions) {
        List<TeamVO> teamVOS = new ArrayList<>();
        if (teamConditions != null) {
            List<Team> teams = teamMapper.selectTeamByConditions(teamConditions);
            log.info("目前查询到{}条队伍信息", teams.size());
            for (Team team : teams) {
                Event eventCondition = new Event();
                eventCondition.setId(team.getEventId());
                List<EventVO> eventVOS = eventInfoService.showSearchedEvents(eventCondition);
                TeamVO teamVO = new TeamVO(team.getId(), team.getName(), team.getCountry(), team.getCoach(),
                        team.getInfo(), eventVOS.get(0));
                teamVOS.add(teamVO);
            }
        }
        return teamVOS;
    }

    public List<AthleteVO> showSearchedAthletes(AthleteVO athleteVO) {
        List<AthleteVO> athleteVOS = athleteMapper.selectAthleteVOByCondition(athleteVO);
        return athleteVOS;
    }

    public void importTeams(File file) throws Exception {
        List<Team> teamList = new ArrayList<>();

        try (FileInputStream fis = new FileInputStream(file);
             Workbook workbook = new XSSFWorkbook(fis)) {
            Sheet sheet = workbook.getSheetAt(0);
            TeamDataImporter teamImporter = new TeamDataImporter(this, eventInfoService);
            Set<String> nameSet = teamImporter.selectAliveNames();

            for (Row row : sheet) {
                if (row.getRowNum() == 0) continue;  // Skip header row

                Team team = extractTeamFromRow(row); // Extract Team from row

                if (!teamImporter.validate(team)) {
                    continue;
                }

                if (!nameSet.contains(team.getEventId() + team.getName())) {
                    teamList.add(team);
                    nameSet.add(team.getEventId() + team.getName());
                }
            }
            teamMapper.insertTeams(teamList);
        }
    }

    public void importAthletes(File file) throws Exception {
        List<Athlete> athleteList = new ArrayList<>();

        try (FileInputStream fis = new FileInputStream(file);
             Workbook workbook = new XSSFWorkbook(fis)) {
            Sheet sheet = workbook.getSheetAt(0);
            AthleteDataImporter athleteImporter = new AthleteDataImporter(this);

            for (Row row : sheet) {
                if (row.getRowNum() == 0) continue;  // Skip header row

                AthleteVO athleteVO = extractAthleteFromRow(row);  // Extract Athlete from row

                if (!athleteImporter.validate(athleteVO)) {
                    continue;
                }

                Athlete athlete = athleteImporter.processForeignKeys(athleteVO);
                athleteList.add(athlete);
            }
            athleteMapper.insertAthletes(athleteList);
        }
    }

    private AthleteVO extractAthleteFromRow(Row row) {
        String name = getCellValue(row, 0);
        String teamName = getCellValue(row, 1);
        String birthDate = getCellValue(row, 2);
        GenderEnum genderEnum = GenderEnum.fromDisplayName(row.getCell(3).getStringCellValue());
        Double l = Double.valueOf(getCellValue(row, 4));
        String category = getCellValue(row, 5);
        Long eventId = l.longValue();

        AthleteVO athleteVO = new AthleteVO(null, name, genderEnum, birthDate, null, null, category);
        Team team = new Team();
        team.setName(teamName);
        Event event = new Event();
        event.setId(eventId);
        athleteVO.setEvent(event);
        athleteVO.setTeam(team);
        return athleteVO;
    }

    private Team extractTeamFromRow(Row row) {
        String name = getCellValue(row, 0);
        Double v = Double.valueOf(getCellValue(row, 1));
        Long eventId = v.longValue();
        String country = getCellValue(row, 2);
        String coach = getCellValue(row, 3);
        String info = getCellValue(row, 4);
        int seed = 0;

        return new Team(null, eventId, name, country, coach, info, seed);
    }

    private String getCellValue(Row row, int index) {
        Cell cell = row.getCell(index);
        if (cell == null) {
            return "";
        }
        // 处理不同的单元格类型
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    // 将日期格式化为字符串
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    return sdf.format(cell.getDateCellValue());  // 使用指定格式
                } else {
                    return String.valueOf(cell.getNumericCellValue());  // 如果是数字，返回其字符串表示
                }
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                return cell.getCellFormula();
            default:
                return "";
        }
    }
}
